/*
//
//              INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license  agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in  accordance  with the terms of that agreement.
//    Copyright (c) 2007-2008 Intel Corporation. All Rights Reserved.
//
//
*/

#include "umc_defs.h"
#if defined(UMC_ENABLE_AVS_VIDEO_DECODER)

#include <trace_log.h>
#include "umc_avs_dec_decompressor.h"
#include "umc_avs_picture_header.h"
#include "umc_avs_mb_info.h"
#include "umc_avs_dec_tables.h"
#include "umc_avs_pic.h"

namespace UMC
{

void AVSDecompressor::ReconstructBMacroBlocksRow(void)
{
    MbMax = m_recCtx.MbIndex + m_recCtx.MbWidth;

    // we can use MbIndex either from decoding and reconstructing contexts
    MbIndex = m_recCtx.MbIndex;

    // set coeffs buffers
    m_pReadCoeffs = m_recCtx.m_pCoeffs;

    PrepareNeighbours(&m_recCtx);
    PrepareReconstruction(true);

    do
    {
        WRITE_TRACE_LOG_MB_TITLE(_rec_tst, MbIndex, m_recCtx.MbWidth, m_recCtx.MbHeight, 0 == m_recCtx.m_pPicHeader->progressive_frame);

        // reconstruct next macroblock
        if (I_8x8 != m_pMbInfo->MbType)
        {
            ReconstructBMacroBlock();
        }
        else
        {
            ReconstructIMacroBlock();
        }

        MbIndex += 1;
        AdvanceNeighbours();
        AdvanceReconstruction();

    } while (MbIndex < MbMax);

    // update context
    FinalizeReconstruction();

} // void AVSDecompressor::ReconstructBMacroBlocksRow(void)

void AVSDecompressor::ReconstructBMacroBlock(void)
{
    Ipp32u chromaQP;

    WRITE_TRACE_LOG(_rec_tst, "CurrentQP", m_pMbInfo->QP);

    // compensate luminance motion
    CompensateMotionLumaBMacroBlock();

    // reconstruct luminance blocks
    if (m_pMbInfo->MbCBP & 0x0f)
    {
        ippiReconstructLumaInter_AVS_16s8u_C1R((Ipp16s **) &m_pReadCoeffs,
                                               m_recCtx.m_pPlanes8u[0],
                                               m_recCtx.m_iPitch,
                                               m_pMbInfo->NumCoeffs,
                                               m_pMbInfo->MbCBP,
                                               m_pMbInfo->QP);
    }

    WRITE_TRACE_LOG_BYTE_BLOCK(_rec_tst, "Y block", m_recCtx.m_pPlanes8u[0], m_recCtx.m_iPitch, 16, 16);

    chromaQP = AVSChromaQPTable[m_pMbInfo->QP];
    WRITE_TRACE_LOG(_rec_tst, "chromaQP", chromaQP);

    // compensate chrominance motion
    CompensateMotionChromaBMacroBlock();

    // reconstruct chrominance blocks
    if (m_pMbInfo->MbCBP & 0x0f0)
    {
        ippiReconstructChromaInter_AVS_16s8u_C1R((Ipp16s **) &m_pReadCoeffs,
                                                 m_recCtx.m_pPlanes8u[1],
                                                 m_recCtx.m_pPlanes8u[2],
                                                 m_recCtx.m_iPitch,
                                                 m_pMbInfo->NumCoeffs + 4,
                                                 m_pMbInfo->MbCBP >> 4,
                                                 chromaQP);
    }

    WRITE_TRACE_LOG_BYTE_BLOCK(_rec_tst, "U block", m_recCtx.m_pPlanes8u[1], m_recCtx.m_iPitch, 8, 8);
    WRITE_TRACE_LOG_BYTE_BLOCK(_rec_tst, "V block", m_recCtx.m_pPlanes8u[2], m_recCtx.m_iPitch, 8, 8);

} // void AVSDecompressor::ReconstructBMacroBlock(void)

} // namespace UMC

#endif // defined(UMC_ENABLE_AVS_VIDEO_DECODER)
